import { SearchColumn } from '../types/index';
import { FormSchema } from '/@/components/Form/index';
import { ComponentType } from '/@/components/Form/src/types';

import { ConditionInputSearch } from '../components/conditionsSearch';

import { isObject, isArray, isDef, isEmpty } from '/@/utils/is';
import { SEARCH_TYPE } from '../types/index';
import { DICT } from '/@/enums/dict';
import { getDictTypeListApi } from '/@/api/admin/dict';
import { getItemColConfig } from './useComFormModel';
import { defHttp } from '/@/utils/http/axios';
import dayjs from 'dayjs';
import { useUserStore } from '/@/store/modules/user';

// import { ref, unref } from 'vue';

// import { useMessage } from '/@/hooks/web/useMessage';

// 表单查询配置
export async function useSearchForm(
  searchColumns: SearchColumn[],
  tableFn: Indexable<Fn> = {},
): Promise<NonNullable<FormSchema[]>> {
  const conditionOption = await getContionOption();
  const userStore = useUserStore();

  const res = searchColumns.map(
    ({
      dataIndex,
      title,
      labelSpan,
      colNum,
      searchType,
      options,
      displayCondition,
      relaTableInfo,
      event,
    }) => {
      const component = getComponent(searchType);
      const { itemProps, colProps } = getItemColConfig(labelSpan || 6, colNum || 6, {
        md: 8,
      });
      itemProps.labelAlign = 'right';

      if (searchType === SEARCH_TYPE.CONDITON) {
        // autoLink
        itemProps.autoLink = false;
      }
      const render: FormSchema['render'] = getRender(searchType, { title, conditionOption });
      const optionR = getOptions(searchType, { options, displayCondition });
      const labelInValue = isConditionOptionType(searchType);
      const field = getField(searchType, dataIndex, relaTableInfo);

      const onChange = getFormItemCustomEvent({ event, userInfo: userStore.getUserInfo }, tableFn);
      return {
        field,
        label: title,
        component,
        itemProps,
        componentProps: {
          style: 'width:100%',
          showTime: false,
          options: optionR,
          labelInValue,
          onChange,
        },
        render,
        colProps,
      };
    },
  );

  return res as FormSchema[];
}

// 表单查询参数条件解析
export function handleSearchInfoFn(params) {
  const conditions: Indexable = {};

  for (const [field, val] of Object.entries(params)) {
    if (isObject(val)) {
      const { value, operation } = val;
      conditions[field] = {
        value,
        operation,
      };
    } else if (isArray(val)) {
      conditions[field] = { value: JSON.stringify(val) };
    } else if (isDef(val)) {
      conditions[field] = { value: val };
    }
  }

  return { conditions };
}
export function beforeFetch({ size, current, conditions }) {
  return { size, current, conditions };
}

// 表关联查询或者字段查询
function getField(searchType: number, field: string, relaTableInfo: Recordable) {
  if ([SEARCH_TYPE.REAL_TABLE].includes(searchType)) {
    return relaTableInfo.mainField;
  }

  return field;
}
function isConditionOptionType(searchType: number) {
  return [SEARCH_TYPE.OPTIONS].includes(searchType);
}
// 表关联查询或者字段查询
function getOptions(searchType: number, { options, displayCondition }) {
  if ([SEARCH_TYPE.REAL_TABLE, SEARCH_TYPE.DICT].includes(searchType)) {
    return options;
  }
  // 分类值查询
  if (isConditionOptionType(searchType)) {
    return displayCondition;
  }
}

function getComponent(searchType: number): ComponentType {
  if ([SEARCH_TYPE.REAL_TABLE, SEARCH_TYPE.DICT, SEARCH_TYPE.OPTIONS].includes(searchType)) {
    return 'Select';
  }

  if (searchType === SEARCH_TYPE.DATE) {
    return 'RangePicker';
  }

  return 'Input';
}

async function getContionOption(): Promise<any[]> {
  try {
    return await getDictTypeListApi({ type: DICT.CONDITION_SYMBOL });
  } catch (error) {
    return [];
  }
}

function getRender(
  searchType: number,
  {
    title,
    conditionOption,
  }: {
    title: string;
    conditionOption: any[];
  },
): FormSchema['render'] {
  if (searchType === SEARCH_TYPE.CONDITON) {
    return ({ model, field }) => {
      return (
        <ConditionInputSearch
          placeholder={`请输入${title}`}
          conditions={conditionOption}
          vModel={[model[field], 'modelValue']}
        />
      );
    };
  }
}

function getFormItemCustomEvent(data, tableFn: Indexable<Fn> = {}): any {
  const { event, userInfo } = data;

  if (event && !isEmpty(event)) {
    const fn = new Function(
      'context',
      'args',
      'defHttp',
      `return (async function(context,args,defHttp){${event}})(context,args,defHttp)`,
    );
    return (...args) => {
      const formActionType = tableFn.getForm() || {};

      let formModel = {};
      if (formActionType.getFieldsValue) {
        formModel = formActionType?.getFieldsValue();
      }
      const context = {
        formActionType,
        formModel,
        dayjs,
        userInfo,
        tableActionType: tableFn,
      };

      fn(context, args, defHttp);
    };
  }
}
